Modelos#
# Librerias
import warnings
warnings.filterwarnings('ignore')
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.figure_factory as ff
import plotly.express as px
# Librerias para modelos
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_absolute_percentage_error, mean_squared_error, r2_score, make_scorer
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from xgboost import XGBRegressor
from sklearn.neural_network import MLPRegressor
import joblib
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
# Definir la paleta de colores personalizada
custom_colors = ['#1F3040', '#B9CDCA', '#F2C6AC', '#D99982', '#735749']
# Cargar datos
ventas = pd.read_csv('C:/UNINORTE/VC/Proyecto2/Archivos_Finales/datosventas.csv')
ventas.describe().T
| count | mean | std | min | 25% | 50% | 75% | max | |
|---|---|---|---|---|---|---|---|---|
| lat | 155105.0 | 5.652091e+00 | 2.204566e+00 | 3.254000e+00 | 4.648077e+00 | 4.721532e+00 | 6.210060e+00 | 1.104366e+01 |
| long | 155105.0 | -7.487562e+01 | 8.883420e-01 | -7.657500e+01 | -7.557198e+01 | -7.420027e+01 | -7.406731e+01 | -7.396190e+01 |
| price | 155105.0 | 4.984872e+08 | 4.051956e+08 | 2.000000e+06 | 2.400000e+08 | 3.750000e+08 | 6.000000e+08 | 4.900000e+09 |
| rooms | 155105.0 | 3.003527e+00 | 1.033709e+00 | 1.000000e+00 | 2.000000e+00 | 3.000000e+00 | 3.000000e+00 | 7.000000e+00 |
| baths | 155105.0 | 2.559737e+00 | 1.121071e+00 | 0.000000e+00 | 2.000000e+00 | 2.000000e+00 | 3.000000e+00 | 7.000000e+00 |
| park | 155105.0 | 1.182457e+00 | 9.385399e-01 | 0.000000e+00 | 1.000000e+00 | 1.000000e+00 | 2.000000e+00 | 5.000000e+00 |
| area_privada | 155105.0 | 1.114881e+02 | 6.199171e+01 | 1.000000e+00 | 6.500000e+01 | 9.400000e+01 | 1.390000e+02 | 3.250000e+02 |
| area_const | 155105.0 | 1.139092e+02 | 6.337710e+01 | 1.000000e+00 | 6.600000e+01 | 9.600000e+01 | 1.440000e+02 | 3.319651e+02 |
| admon | 155105.0 | 3.498544e+05 | 2.571560e+05 | 0.000000e+00 | 1.600000e+05 | 2.840000e+05 | 4.790000e+05 | 2.118338e+06 |
| Estrato | 155105.0 | 4.101970e+00 | 9.879393e-01 | 1.000000e+00 | 3.000000e+00 | 4.000000e+00 | 5.000000e+00 | 6.000000e+00 |
| Piso No | 112509.0 | 3.753531e+00 | 3.098129e+00 | 1.000000e+00 | 1.000000e+00 | 3.000000e+00 | 5.000000e+00 | 1.600000e+01 |
ventas.head()
| lat | long | category | price | rooms | baths | park | ciudad | barrio | area_privada | area_const | admon | Estrato | Estado | Antiguedad | Piso No | Tipo de Apartamento | Sector | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 3.377575 | -76.523969 | Apartamento | 197000000.0 | 2 | 2 | 1 | Cali | Ciudad Bochalema | 64.0 | 64.0 | 178000.000000 | 4 | No Especificado | 1 a 8 años | NaN | No Especificado | Ciudad Bochalema |
| 1 | 4.563951 | -74.107534 | Apartaestudio | 70000000.0 | 1 | 1 | 0 | Bogotá | Las Lomas | 30.0 | 30.0 | 45000.000000 | 2 | No Especificado | 16 a 30 años | NaN | No Especificado | Las Lomas |
| 2 | 6.264103 | -75.603076 | Apartamento | 235000000.0 | 3 | 2 | 1 | Medellín | Calasanz Occidente | 56.0 | 56.0 | 192139.000000 | 3 | No Especificado | No Especificado | 13.0 | No Especificado | No Especificado |
| 3 | 10.993099 | -74.817276 | Apartaestudio | 139000000.0 | 1 | 1 | 1 | Barranquilla | Ciudad Jardín | 43.0 | 43.0 | 145000.000000 | 4 | No Especificado | No Especificado | 4.0 | No Especificado | No Especificado |
| 4 | 6.248413 | -75.563910 | Apartamento | 260000000.0 | 4 | 2 | 0 | Medellín | Centro | 115.0 | 115.0 | 177878.235981 | 4 | 4.0 | 9 a 15 años | 3.0 | No Especificado | Centro |
# Seleccionar columnas numericas
columnas_numericas = ventas.select_dtypes(include=['int', 'float']).columns
# Guardar los nombres de las columnas numericas en una lista
nombre_columna_numericas = list(columnas_numericas )
# Calcular la matriz de correlación
corr_matrix = ventas[nombre_columna_numericas].corr()
# Crear el gráfico de la matriz de correlación
fig = ff.create_annotated_heatmap(
z=corr_matrix.to_numpy(),
x=list(corr_matrix.columns),
y=list(corr_matrix.index),
annotation_text=corr_matrix.round(2).to_numpy(),
showscale=True,
colorscale=custom_colors
)
fig.update_layout(title='Matriz de Correlación', xaxis_title='Variables', yaxis_title='Variables')
fig.show()
Preprocesamiento#
Dado que las variables ‘lat’ y ‘long’ explican lo mismo que las variables ‘ciudad’, ‘barrio’ y ‘sector’, lo cual es más que evidente en la gráfica de associations de vista en el EDA; para nuestras predicciones utilizaremos solo ‘lat’ y ‘long’.
La variable ‘Piso No’ también será excluida de nuestro análisis al tener demasiados valores nulos, que no pudieron ser imputados con ninguna técnica de imputación, adicionalmente solo tiene una explicación para una de las categorías de inmuebles.
Por otro lado, las variables ‘area_privada’ y ‘area_const’ tienen una correlación de 0.98, por ende, solo utilizaremos una de ellas, en este caso ‘area_const’.
ventas = ventas.drop(['ciudad','barrio', 'Piso No', 'Sector','area_privada'],axis=1)
# Seleccionar columnas categóricas
columnas_categoricas = ventas.select_dtypes(include=['object', 'category']).columns
# Guardar los nombres de las columnas categóricas en una lista
nombre_columna_categorica = list(columnas_categoricas)
# Seleccionar columnas numericas
columnas_numericas = ventas.select_dtypes(include=['int', 'float']).columns
# Guardar los nombres de las columnas numericas en una lista
nombre_columna_numericas = list(columnas_numericas )
# Mostrar la lista de nombres de columnas
print(nombre_columna_categorica)
print(nombre_columna_numericas)
['category', 'Estado', 'Antiguedad', 'Tipo de Apartamento']
['lat', 'long', 'price', 'rooms', 'baths', 'park', 'area_const', 'admon', 'Estrato']
# Separar datos en variables predictoras y variable de interes
X = ventas.drop(['price'],axis=1)
y = ventas['price']
# Dividir los datos en conjuntos de entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=68)
def calcular_metricas(X_trainval, y_trainval, X_test, y_test, best_model):
# Realizar predicciones en el conjunto de entrenamiento (X_trainval)
y_pred_train = best_model.predict(X_trainval)
# Realizar predicciones en el conjunto de prueba (X_test)
y_pred_test = best_model.predict(X_test)
# Calcular las métricas utilizando los datos de entrenamiento y validación
mape_tra = mean_absolute_percentage_error(y_trainval, y_pred_train)
rmse_tra = np.sqrt(mean_squared_error(y_trainval, y_pred_train))
r2_tra = r2_score(y_trainval, y_pred_train)
# Calcular las métricas utilizando los datos de prueba (X_test, y_test)
mape_test = mean_absolute_percentage_error(y_test, y_pred_test)
rmse_test = np.sqrt(mean_squared_error(y_test, y_pred_test))
r2_test = r2_score(y_test, y_pred_test)
return mape_tra, rmse_tra, r2_tra, mape_test, rmse_test, r2_test
def plot_residuals(y_true, y_pred):
# Calcula los residuos
residuos = y_true - y_pred
# Gráfico de dispersión de residuos
fig = go.Figure()
fig.add_trace(go.Scatter(x=y_pred, y=residuos, mode='markers', name='Residuos',
marker=dict(color=custom_colors[3])))
fig.add_hline(y=0, line_dash="dash", line_color=custom_colors[0])
fig.update_layout(
title='Diagrama de Residuos',
xaxis_title='Valores Predichos',
yaxis_title='Residuos',
showlegend=False
)
fig.show()
# Histograma de los residuos
fig = go.Figure()
fig.add_trace(go.Histogram(x=residuos, marker_color=custom_colors[2]))
fig.update_layout(
title='Histograma de Residuos',
xaxis_title='Residuos',
yaxis_title='Frecuencia',
bargap=0.05
)
fig.show()
def plot_real_vs_predicted(y_real, y_pred, filename):
# Crear DataFrame con los valores reales y predichos
df = pd.DataFrame({
'Y Real': y_real,
'Y Predicho': y_pred
})
# Guardar los datos en un archivo CSV
#df.to_csv(filename, index=False)
# Crear el gráfico de dispersión para comparar los valores reales y predichos
fig = go.Figure()
fig.add_trace(go.Scatter(x=y_real, y=y_pred, mode='markers', name='Real vs Predicho',
marker=dict(color=custom_colors[3])))
fig.add_trace(go.Scatter(x=y_real, y=y_real, mode='lines', name='Comportamiento Ideal',
line=dict(color=custom_colors[0], dash='dash')))
fig.update_layout(title='Comparación de Y Real vs Y Predicho',
xaxis_title='Y Real',
yaxis_title='Y Predicho',
legend_title='Leyenda')
fig.show()
Modelo Ridge#
# Identificar las columnas categóricas
#categorical_features = nombre_columna_categorica
#column_transformer = ColumnTransformer(
# transformers=[
# ('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features)
# ],
# remainder='passthrough' # esto pasa las otras columnas numéricas sin cambios
#)
## Crear un pipeline que primero transforme los datos y luego aplique el modelo Ridge
#pipeline = Pipeline(steps=[
# ('preprocessor', column_transformer),
# ('regressor', Ridge())
#])
## Definir los parámetros para buscar utilizando GridSearchCV
#param_grid = {
# 'regressor__alpha': [0.1, 1, 10, 50, 100, 200, 1000], # Diferentes valores de regularización
# 'regressor__solver': ['auto', 'svd', 'cholesky', 'lsqr', 'sparse_cg']
#}
## Definir el scorer para el GridSearchCV
#mse_scorer = make_scorer(mean_squared_error, greater_is_better=False)
## Realizar una búsqueda de cuadrícula para encontrar los mejores parámetros
#grid_search = GridSearchCV(pipeline, param_grid, cv=5, scoring=mse_scorer, verbose=2, n_jobs=-1)
#grid_search.fit(X_train, y_train)
## El mejor modelo resultante del GridSearchCV
#best_model = grid_search.best_estimator_
best_model = joblib.load("mejor_modelo_ridge.joblib")
# Calcular las métricas para el mejor modelo
mape_ridget, rmse_ridget, r2_ridget, mape_ridge, rmse_ridge, r2_ridge = calcular_metricas(X_train, y_train, X_test, y_test, best_model)
# Imprimir las métricas
print(f'MAPE en el conjunto de entrenamiento: {mape_ridget}')
print(f'RMSE en el conjunto de entrenamiento: {rmse_ridget}')
print(f'R^2 en el conjunto de entrenamiento: {r2_ridget}')
#print("Mejores parámetros encontrados: ", grid_search.best_params_)
# Imprimir las métricas
print(f'MAPE en el conjunto de prueba: {mape_ridge}')
print(f'RMSE en el conjunto de prueba: {rmse_ridge}')
print(f'R^2 en el conjunto de prueba: {r2_ridge}')
# Guardar el modelo en un archivo
#joblib.dump(best_model, 'mejor_modelo_ridge.joblib')
MAPE en el conjunto de entrenamiento: 0.3270766638873291
RMSE en el conjunto de entrenamiento: 196719169.17808387
R^2 en el conjunto de entrenamiento: 0.765151663063854
MAPE en el conjunto de prueba: 0.3328104239732556
RMSE en el conjunto de prueba: 196370084.51321307
R^2 en el conjunto de prueba: 0.7616582800487592
y_pred = best_model.predict(X_test)
plot_residuals(y_test, y_pred)
feature_names = X_test.columns.tolist()
plot_real_vs_predicted(y_test, y_pred, filename='real_vs_predicted_ridge.csv')
# Acceder al modelo Ridge y a los coeficientes dentro del pipeline
ridge_model = best_model.named_steps['regressor']
ridge_coefs = ridge_model.coef_
# Acceder a los nombres de las características transformadas
feature_names_transformed = best_model.named_steps['preprocessor'].get_feature_names_out()
# Crear DataFrame para los coeficientes y características
if len(feature_names_transformed) != len(ridge_coefs):
print("La longitud de los nombres de las características transformadas no coincide con los coeficientes.")
else:
coefs = pd.DataFrame({
'feature': feature_names_transformed,
'coefficient': ridge_coefs
})
coefs['abs_coefficient'] = coefs['coefficient'].abs()
# Ordenar las características por la importancia absoluta de sus coeficientes de mayor a menor
coefs = coefs.sort_values(by='abs_coefficient')
# Guardar en un archivo CSV
#coefs.to_csv('FeatureImportances_ridge.csv', index=False)
# Creando el gráfico con Plotly
fig = px.bar(coefs, y='feature', x='abs_coefficient', orientation='h',
title='Importancia de las Características - Ridge Regression', color_discrete_sequence=custom_colors)
fig.show()
Modelo Lasso#
## Identificar las columnas categóricas
#categorical_features = nombre_columna_categorica
#column_transformer = ColumnTransformer(
# transformers=[
# ('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features)
# ],
# remainder='passthrough' # esto pasa las otras columnas numéricas sin cambios
#)
## Crear un pipeline que primero transforme los datos y luego aplique el modelo Lasso
#pipeline = Pipeline(steps=[
# ('preprocessor', column_transformer),
# ('regressor', Lasso(random_state=0))
#])
## Definir los parámetros para buscar utilizando GridSearchCV
#param_grid = {
# 'regressor__alpha': [0.001, 0.01, 0.1, 1.0, 10, 100], # Diferentes valores de regularización
# 'regressor__max_iter': [1000, 5000, 10000], # Ajustar si es necesario para asegurar la convergencia
# 'regressor__fit_intercept': [True, False],
#}
## Definir el scorer para el GridSearchCV
#mse_scorer = make_scorer(mean_squared_error, greater_is_better=False)
## Realizar una búsqueda de cuadrícula para encontrar los mejores parámetros
#grid_search = GridSearchCV(pipeline, param_grid, cv=5, scoring=mse_scorer, verbose=2, n_jobs=-1)
#grid_search.fit(X_train, y_train)
# El mejor modelo resultante del GridSearchCV
best_model = joblib.load("mejor_modelo_lasso.joblib")
# Calcular las métricas para el mejor modelo
mape_lassot, rmse_lassot, r2_lassot, mape_lasso, rmse_lasso, r2_lasso = calcular_metricas(X_train, y_train, X_test, y_test, best_model)
# Imprimir las métricas
print(f'MAPE en el conjunto de entrenamiento: {mape_lassot}')
print(f'RMSE en el conjunto de entrenamiento: {rmse_lassot}')
print(f'R^2 en el conjunto de entrenamiento: {r2_lassot}')
#print("Mejores parámetros encontrados: ", grid_search.best_params_)
# Imprimir las métricas
print(f'MAPE en el conjunto de prueba: {mape_lasso}')
print(f'RMSE en el conjunto de prueba: {rmse_lasso}')
print(f'R^2 en el conjunto de prueba: {r2_lasso}')
## Guardar el modelo en un archivo
#joblib.dump(best_model, 'mejor_modelo_lasso.joblib')
MAPE en el conjunto de entrenamiento: 0.32706308906856385
RMSE en el conjunto de entrenamiento: 196718801.4310985
R^2 en el conjunto de entrenamiento: 0.7651525411144026
MAPE en el conjunto de prueba: 0.3328245848799931
RMSE en el conjunto de prueba: 196372547.9475254
R^2 en el conjunto de prueba: 0.7616523000864321
y_pred = best_model.predict(X_test)
plot_residuals(y_test, y_pred)
feature_names = X_test.columns.tolist()
plot_real_vs_predicted(y_test, y_pred, filename='real_vs_predicted_lasso.csv')
# Acceder al modelo Lasso y a los coeficientes dentro del pipeline
lasso_model = best_model.named_steps['regressor']
lasso_coefs = lasso_model.coef_
# Acceder a los nombres de las características transformadas
feature_names_transformed = best_model.named_steps['preprocessor'].get_feature_names_out()
# Crear DataFrame para los coeficientes y características
if len(feature_names_transformed) != len(lasso_coefs):
print("La longitud de los nombres de las características transformadas no coincide con los coeficientes.")
else:
coefs = pd.DataFrame({
'feature': feature_names_transformed,
'coefficient': lasso_coefs
})
coefs['abs_coefficient'] = coefs['coefficient'].abs()
# Ordenar las características por la importancia absoluta de sus coeficientes de mayor a menor
coefs = coefs.sort_values(by='abs_coefficient')
# Guardar en un archivo CSV
#coefs.to_csv('FeatureImportances_lasso.csv', index=False)
# Creando el gráfico con Plotly
fig = px.bar(coefs, y='feature', x='abs_coefficient', orientation='h',
title='Importancia de las Características - Lasso Regression', color_discrete_sequence=custom_colors)
fig.show()
Modelo XGBoots#
## Identificar las columnas categóricas
#categorical_features = nombre_columna_categorica
#column_transformer = ColumnTransformer(
# transformers=[
# ('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features)
# ],
# remainder='passthrough' # esto pasa las otras columnas numéricas sin cambios
#)
## Crear un pipeline que primero transforme los datos y luego aplique el modelo XGBoost
#pipeline = Pipeline(steps=[
# ('preprocessor', column_transformer),
# ('regressor', XGBRegressor(objective='reg:squarederror', random_state=0))
#])
## Definir los parámetros para buscar utilizando GridSearchCV
#param_grid = {
# 'regressor__n_estimators': [50, 100, 200],
# 'regressor__learning_rate': [0.01, 0.1, 0.3],
# 'regressor__max_depth': [3, 5, 7]
#}
## Definir el scorer para el GridSearchCV
#mse_scorer = make_scorer(mean_squared_error, greater_is_better=False)
## Realizar una búsqueda de cuadrícula para encontrar los mejores parámetros
#grid_search = GridSearchCV(pipeline, param_grid, cv=5, scoring=mse_scorer, verbose=2, n_jobs=-1)
#grid_search.fit(X_train, y_train)
# El mejor modelo resultante del GridSearchCV
best_model = joblib.load("mejor_modelo_xgboots.joblib")
# Calcular las métricas para el mejor modelo
mape_xgboostt, rmse_xgboostt, r2_xgboostt, mape_xgboost, rmse_xgboost, r2_xgboost = calcular_metricas(X_train, y_train, X_test, y_test, best_model)
# Imprimir las métricas
print(f'MAPE en el conjunto de entrenamiento: {mape_xgboostt}')
print(f'RMSE en el conjunto de entrenamiento: {rmse_xgboostt}')
print(f'R^2 en el conjunto de entrenamiento: {r2_xgboostt}')
#print("Mejores parámetros encontrados: ", grid_search.best_params_)
# Imprimir las métricas
print(f'MAPE en el conjunto de prueba: {mape_xgboost}')
print(f'RMSE en el conjunto de prueba: {rmse_xgboost}')
print(f'R^2 en el conjunto de prueba: {r2_xgboost}')
## Guardar el modelo en un archivo
#joblib.dump(best_model, 'mejor_modelo_xgboots.joblib')
MAPE en el conjunto de entrenamiento: 0.1335809267109008
RMSE en el conjunto de entrenamiento: 72816745.63153034
R^2 en el conjunto de entrenamiento: 0.9678221771360337
MAPE en el conjunto de prueba: 0.1924401789399948
RMSE en el conjunto de prueba: 107622322.47698922
R^2 en el conjunto de prueba: 0.9284097078636615
y_pred = best_model.predict(X_test)
plot_residuals(y_test, y_pred)
feature_names = X_test.columns.tolist()
plot_real_vs_predicted(y_test, y_pred, filename='real_vs_predicted_XGBoots.csv')
##'best_model' es tu modelo XGBoost ya entrenado dentro de un pipeline
#xgb_model = best_model.named_steps['regressor']
## Obtener las importancias de las características. Asumiendo que el modelo está entrenado.
#feature_importances = xgb_model.feature_importances_
## Acceder a los nombres de las características transformadas
#feature_names_transformed = best_model.named_steps['preprocessor'].get_feature_names_out()
## Crear DataFrame para las importancias de características
#importances = pd.DataFrame({
# 'feature': feature_names_transformed,
# 'importance': feature_importances
#})
# Ordenar las características por la importancia de mayor a menor
#importances_sorted = importances.sort_values(by='importance')
importances_sorted = pd.read_csv('C:/UNINORTE/VC/Proyecto2/Archivos_Finales/FeatureImportances_xgboost.csv')
# Guardar en un archivo CSV
#importances_sorted.to_csv('FeatureImportances_xgboost.csv', index=False)
# Crear el gráfico con Plotly
fig = px.bar(importances_sorted, x='importance', y='feature', title='Importancia de las Características - XGBoost',
labels={'feature': 'Características', 'importance': 'Importancia'},
orientation='h', color_discrete_sequence=custom_colors)
fig.show()
Modelo MLP#
## Identificar las columnas categóricas
#categorical_features = nombre_columna_categorica
#column_transformer = ColumnTransformer(
# transformers=[
# ('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features)
# ],
# remainder='passthrough' # Esto pasa las otras columnas numéricas sin cambios
#)
## Crear un pipeline que primero transforme los datos y luego aplique el modelo MLP
#pipeline = Pipeline(steps=[
# ('preprocessor', column_transformer),
# ('regressor', MLPRegressor(random_state=1))
#])
## Definir los parámetros para buscar utilizando GridSearchCV
#param_grid = {
# 'regressor__hidden_layer_sizes': [(50,), (100,)], # Varias configuraciones de capas ocultas
# 'regressor__alpha': [0.001, 0.01, 0.1], # Rango extendido de parámetro de regularización L2
# 'regressor__learning_rate_init': [0.005, 0.01], # Tasa de aprendizaje inicial con más opciones
# 'regressor__max_iter': [200, 300], # Rango extendido de número máximo de iteraciones
#}
## Definir el scorer para el GridSearchCV
#mse_scorer = make_scorer(mean_squared_error, greater_is_better=False)
## Realizar una búsqueda de cuadrícula para encontrar los mejores parámetros
#grid_search = GridSearchCV(pipeline, param_grid, cv=5, scoring=mse_scorer, verbose=2, n_jobs=-1)
#grid_search.fit(X_train, y_train)
# El mejor modelo resultante del GridSearchCV
best_model = joblib.load("mejor_modelo_mpl.joblib")
## Imprimir las métricas
#print("Mejores parámetros encontrados: ", grid_search.best_params_)
# Calcular las métricas para el mejor modelo
mape_mlpt, rmse_mlpt, r2_mlpt, mape_mlp, rmse_mlp, r2_mlp = calcular_metricas(X_train, y_train, X_test, y_test, best_model)
# Imprimir las métricas
print(f'MAPE en el conjunto de entrenamiento: {mape_mlpt}')
print(f'RMSE en el conjunto de entrenamiento: {rmse_mlpt}')
print(f'R^2 en el conjunto de entrenamiento: {r2_mlpt}')
#print("Mejores parámetros encontrados: ", grid_search.best_params_)
# Imprimir las métricas
print(f'MAPE en el conjunto de prueba: {mape_mlp}')
print(f'RMSE en el conjunto de prueba: {rmse_mlp}')
print(f'R^2 en el conjunto de prueba: {r2_mlp}')
## Guardar el modelo en un archivo
#joblib.dump(best_model, 'mejor_modelo_mpl.joblib')
MAPE en el conjunto de entrenamiento: 0.29659783428441644
RMSE en el conjunto de entrenamiento: 192515342.27320886
R^2 en el conjunto de entrenamiento: 0.775081686909593
MAPE en el conjunto de prueba: 0.30390329713346426
RMSE en el conjunto de prueba: 194189460.07168415
R^2 en el conjunto de prueba: 0.7669223002370361
y_pred = best_model.predict(X_test)
plot_residuals(y_test, y_pred)
feature_names = X_test.columns.tolist()
plot_real_vs_predicted(y_test, y_pred, filename='real_vs_predicted_MLP.csv')
# 'best_model' es el modelo MLP ya entrenado dentro de un pipeline
mlp_model = best_model.named_steps['regressor']
# Acceder a los pesos de la primera capa oculta
weights_first_layer = mlp_model.coefs_[0] # Coefs_ es una lista de matrices de coeficientes
# Calcular la importancia aproximada de las características como la suma de los valores absolutos de los pesos
feature_importances = np.sum(np.abs(weights_first_layer), axis=1)
# Acceder a los nombres de las características transformadas
feature_names_transformed = best_model.named_steps['preprocessor'].get_feature_names_out()
# Crear DataFrame para las importancias aproximadas
coefs = pd.DataFrame({
'feature': feature_names_transformed,
'importance': feature_importances
})
# Ordenar las características por importancia
coefs_sorted = coefs.sort_values(by='importance')
# Guardar en un archivo CSV
#coefs_sorted.to_csv('FeatureImportances_mlp.csv', index=False)
# Creando el gráfico con Plotly
fig = px.bar(coefs_sorted, y='feature', x='importance', orientation='h',
title='Importancia Aproximada de las Características - MLP',
color_discrete_sequence=custom_colors)
fig.show()
Resultados#
# Nombres de los modelos
nombres_modelos = ['Ridge', 'Lasso', 'XGBoost', 'MLP']
# Definir las listas de métricas para cada modelo
mape_scores = [mape_ridge, mape_lasso, mape_xgboost, mape_mlp]
rmse_scores = [rmse_ridge, rmse_lasso, rmse_xgboost, rmse_mlp]
r2_scores = [r2_ridge, r2_lasso, r2_xgboost, r2_mlp]
# Crear un DataFrame para almacenar las métricas
df_resultados = pd.DataFrame({
'Modelo': nombres_modelos,
'MAPE': mape_scores,
'RMSE': rmse_scores,
'R^2': r2_scores
})
print(df_resultados)
Modelo MAPE RMSE R^2
0 Ridge 0.332810 1.963701e+08 0.761658
1 Lasso 0.332825 1.963725e+08 0.761652
2 XGBoost 0.192440 1.076223e+08 0.928410
3 MLP 0.303903 1.941895e+08 0.766922
Mejor modelo basado en la métrica RMSE#
# Encontrar el índice del modelo con el RMSE más bajo
indice_mejor_rmse = rmse_scores.index(min(rmse_scores))
# Obtiener el nombre del modelo con el RMSE más bajo
mejor_modelo = nombres_modelos[indice_mejor_rmse]
# Mostrar el modelo con el RMSE más bajo y su valor de RMSE
print(f"El modelo con el RMSE más bajo es {mejor_modelo} con RMSE = {min(rmse_scores)}")
El modelo con el RMSE más bajo es XGBoost con RMSE = 107622322.47698922
Mejor modelo basado en la métrica \(R^2\)#
# Encontrar el índice del modelo con el r2 más alto
indice_mejor_r2 = r2_scores.index(max(r2_scores))
# Obtiener el nombre del modelo con el r2 más alto
mejor_modelo2 = nombres_modelos[indice_mejor_r2]
# Mostrar el modelo con el r2 más alto y su valor de r2
print(f"El modelo con el r2 más alto es {mejor_modelo2} con r2 = {max(r2_scores)}")
El modelo con el r2 más alto es XGBoost con r2 = 0.9284097078636615
Gráfica de métricas#
# Gráfica de R2
fig_r2 = go.Figure()
fig_r2.add_trace(go.Bar(
y=nombres_modelos,
x=r2_scores,
name='R^2',
orientation='h',
marker=dict(color=custom_colors[0])
))
fig_r2.update_layout(
title='Comparación de R^2 entre Modelos',
xaxis=dict(title='R^2'),
yaxis=dict(title='Modelos'),
barmode='group',
bargap=0.15,
bargroupgap=0.1
)
fig_r2.show()
# Gráfica de RMSE
fig_rmse = go.Figure()
fig_rmse.add_trace(go.Bar(
y=nombres_modelos,
x=rmse_scores,
name='RMSE Score',
orientation='h',
marker=dict(color=custom_colors[1])
))
fig_rmse.update_layout(
title='Comparación de RMSE entre Modelos',
xaxis=dict(title='RMSE Score'),
yaxis=dict(title='Modelos'),
barmode='group',
bargap=0.15,
bargroupgap=0.1
)
fig_rmse.show()